﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MCPlatform.Dxf.Utils
{
    public static class TangentialFollowHelper
    {
        /// <summary>
        /// 计算两个点形成的线与X轴正方向的夹角
        /// </summary>
        /// <param name="startXpos"></param>
        /// <param name="startYPos"></param>
        /// <param name="endXPos"></param>
        /// <param name="endYPos"></param>
        /// <returns>角度，默认0度为X轴正方向，顺时针旋转为正角度，逆时针为负角度</returns>
        public static double LineKniteAngle(double startXpos,double startYPos,double endXPos,double endYPos)
        {
            //X轴坐标相等，结束点Y比开始点Y大，在正Y轴上，角度默认是X轴正向，所以是-90度，逆时针
            if ( startXpos == endXPos && startYPos < endYPos)
            {
                return -90;
            }
            else if ( startXpos == endXPos && startYPos > endYPos)
            {
                return 90;
            }

            double angle = 0;
            if ( startXpos < endXPos)
            {
                angle =  -1* 180 * Math.Atan2(endYPos - startYPos,endXPos-startXpos)/Math.PI;
                return AdjustCutterAngle(angle);//调整角度，防止转太多超过180，如果超过换角度
            }
            else if( startXpos > endXPos)
            {
                angle =  -1 * 180 * ( 1 + Math.Atan2(endYPos - startYPos, endXPos - startXpos) / Math.PI);
                return AdjustCutterAngle(angle);//调整角度，防止转太多超过180，如果超过换角度
            }

            return angle;

        }


        /// <summary>
        /// 计算圆弧任意一点，顺时针刀向起始坐标
        /// </summary>
        /// <param name="centerX">圆心X坐标</param>
        /// <param name="centerY">圆心Y坐标</param>
        /// <param name="pointX">任意一点X坐标</param>
        /// <param name="pointY">任意一点Y坐标</param>
        /// <returns>U轴起始角度</returns>
        public static double ClockwiseArcKniteAngle(double centerX,double centerY,double pointX,double pointY)
        {
            if( centerX == pointX && centerY < pointY)
            {
                return 0;
            }
            else if (centerX == pointX && centerY > pointY)
            {
                return 180;
            }


            double angle = 0;
            double dx = pointX - centerX;
            double dy = pointY - centerY;
            if (centerX < pointX)
            {
                angle = 270 + (180 / Math.PI) * Math.Atan2(dy,dx);
            }
            else if (centerX > pointX)
            {
                angle = 90 + (180 / Math.PI) * Math.Atan2(dy, dx);
            }


            return angle;
        }


        /// <summary>
        /// 圆弧任意一点，逆时针刀向起始坐标
        /// </summary>
        /// <param name="centerX">圆心X坐标</param>
        /// <param name="centerY">圆心Y坐标</param>
        /// <param name="pointX">任意一点X坐标</param>
        /// <param name="pointY">任意一点Y坐标</param>
        /// <returns>U轴起始角度</returns>
        public static double CounterClockwiseArcKniteAngle(double centerX, double centerY, double pointX, double pointY)
        {
            if (centerX == pointX && centerY < pointY)
            {
                return 180;
            }
            else if (centerX == pointX && centerY > pointY)
            {
                return 0;
            }


            double angle = 0;
            double dx = pointX - centerX;
            double dy = pointY - centerY;
            if (centerX < pointX)
            {
                angle = 90 + (180 / Math.PI) * Math.Atan2(dy, dx);
            }
            else if (centerX > pointX)
            {
                angle = 270 + (180 / Math.PI) * Math.Atan2(dy, dx);
            }


            return angle;
        }



        /// <summary>
        /// 椭圆上任意一点，顺时针刀向起始坐标
        /// </summary>
        /// <param name="centerX">圆心X坐标</param>
        /// <param name="centerY">圆心Y坐标</param>
        /// <param name="pointX">任意一点X坐标</param>
        /// <param name="pointY">任意一点Y坐标</param>
        /// <returns>U轴起始角度</returns>
        public static double ClockwiseEllipseKniteAngle(double centerX, double centerY, double pointX, double pointY)
        {
            if (centerX == pointX && centerY < pointY)
            {
                return 0;
            }
            else if (centerX == pointX && centerY > pointY)
            {
                return 180;
            }


            double angle = 0;
            double dx = pointX - centerX;
            double dy = pointY - centerY;
            if (centerX < pointX)
            {
                angle =180+  (180 / Math.PI) * Math.Atan2(dy, dx);
            }
            else if (centerX > pointX)
            {
                angle = (180 / Math.PI) * Math.Atan2(dy, dx);
            }


            return angle;
        }


        /// <summary>
        /// 椭圆上任意一点，逆时针切割U轴起始角度
        /// </summary>
        /// <param name="centerX">圆心X坐标</param>
        /// <param name="centerY">圆心Y坐标</param>
        /// <param name="pointX">任意一点X坐标</param>
        /// <param name="pointY">任意一点Y坐标</param>
        /// <returns>U轴起始角度</returns>
        public static double CounterClockwiseEllipseKniteAngle(double centerX, double centerY, double pointX, double pointY)
        {
            if (centerX == pointX && centerY < pointY)
            {
                return 180;
            }
            else if (centerX == pointX && centerY > pointY)
            {
                return 0;
            }


            double angle = 0;
            double dx = pointX - centerX;
            double dy = pointY - centerY;
            if (centerX < pointX)
            {
                angle = (180 / Math.PI) * Math.Atan2(dy, dx);
            }
            else if (centerX > pointX)
            {
                angle =180+ (180 / Math.PI) * Math.Atan2(dy, dx);
            }


            return angle;
        }

        public static double AdjustCutterAngle(double angle)
        {
            // Convert angle to -180 to 180 range
            while (angle > 180)
            {
                angle -= 360;
            }
            while (angle < -180)
            {
                angle += 360;
            }

            return angle;
        }


        public static bool IsCircleClockwise(double startX,double startY,double midX,double midY, double endX,double endY)
        {
            // Calculate vectors AB and BC
            double vectorAB_x = midX - startX;
            double vectorAB_y = midY - startY;
            double vectorBC_x = endX - midX;
            double vectorBC_y = endY - midY;

            // Calculate the cross product AB x BC
            double crossProduct = (vectorAB_x * vectorBC_y) - (vectorAB_y * vectorBC_x);

            // Determine the direction based on the sign of the cross product
            if (crossProduct > 0)
            {
                return false; // 逆时针
            }
            else if (crossProduct < 0)
            {
                return true; // 顺时针
            }
            else
            {
                return true;
                // This case would mean the points are collinear, which theoretically shouldn't happen on a circle
                //throw new Exception("Points are collinear, cannot determine arc direction.");
            }
        }


        public static bool IsEllipseClockwise(double startX, double startY, double centerX, double centerY, double endX, double endY)
        {
            // Calculate vectors AB and BC
            double vectorAB_x = centerX - startX;
            double vectorAB_y = centerY - startY;
            double vectorBC_x = endX - centerX;
            double vectorBC_y = endY - centerY;

            // Calculate the cross product AB x BC
            double crossProduct = (vectorAB_x * vectorBC_y) - (vectorAB_y * vectorBC_x);

            // Determine the direction based on the sign of the cross product
            if (crossProduct > 0)
            {
                return false; // 逆时针
            }
            else if (crossProduct < 0)
            {
                return true; // 顺时针
            }
            else
            {
                return true;
                // This case would mean the points are collinear, which theoretically shouldn't happen on a circle
                //throw new Exception("Points are collinear, cannot determine arc direction.");
            }
        }

    }
}
